﻿
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>MCX One</title>

    <!-- Favicon -->
    <link href="" rel="icon" type="image/x-icon" />

    <!-- placeholders for the theme switcher -->
    <link rel='stylesheet' id='theme_stylesheet'>
    <link rel='stylesheet' id='icon_stylesheet'>
    <style>[class*="foundicon-"] {font-family: GeneralFoundicons;font-style: normal;}</style>

    <!-- JSON Editor -->
    <script src="https://cdn.jsdelivr.net/npm/@json-editor/json-editor/dist/jsoneditor.min.js"></script>

    <!-- LZString compression library - Used to create direct links to the demo - NOT REQUIRED for JSON Editor -->
    <script src="https://cdn.jsdelivr.net/npm/lz-string@1.4.4/libs/lz-string.min.js"></script>

</head>

<body>
<p>&nbsp;</p>
<div class='container'>
    <div class='row'>
        <div class='span8 col-md-8 columns eight large-8 col s8'>
            <h2>MCX One</h2>
            <p>Please define an MCX simulation blow.</p>

            <div id='editor'></div>
        </div>
        <div class='span4 col-md-4 columns four large-4 col s4'>
            <div>
                <a href='#' id='direct_link'>Direct Link</a> (preserves schema, value, and options)
            </div>

            <h2>JSON Input</h2>
            <p><button class='btn btn-primary' id='setvalue'>Update Form</button></p>
            <textarea id='output' style='width: 100%; height: 300px; font-family: monospace;' class='form-control'></textarea>

            <h2>Options</h2>
            <div id='options_holder'>
                <div>
                    <label>CSS Framework</label>
                    <select id='theme_switcher' class='form-control browser-default'>
                        <option value='barebones'>Barebones</option>
                        <option value='html'>HTML</option>
                        <option value='jqueryui'>jQuery UI</option>
                        <option value='bootstrap2'>Bootstrap 2</option>
                        <option value='bootstrap3'>Bootstrap 3</option>
                        <option value='bootstrap4'>Bootstrap 4</option>
                        <option value='foundation3'>Foundation 3</option>
                        <option value='foundation4'>Foundation 4</option>
                        <option value='foundation5'>Foundation 5</option>
                        <option value='foundation6'>Foundation 6</option>
                        <option value='materialize'>Materialize</option>
                    </select>
                </div>
                <div>
                    <label>Icon Library</label>
                    <select id='icon_switcher' class='form-control browser-default'>
                        <option value=''>None</option>
                        <option value='jqueryui'>jQuery UI</option>
                        <option value='bootstrap2'>Bootstrap 2 Glyphicons</option>
                        <option value='bootstrap3'>Bootstrap 3 Glyphicons</option>
                        <option value='foundation2'>Foundicons 2</option>
                        <option value='foundation3'>Foundicons 3</option>
                        <option value='fontawesome3'>FontAwesome 3</option>
                        <option value='fontawesome4'>FontAwesome 4</option>
                        <option value='materialicons'>Material Icons</option>
                    </select>
                </div>
                <div>
                    <label>Object Layout</label>
                    <select id='object_layout' class='form-control browser-default'>
                        <option value='normal'>normal</option>
                        <option value='grid'>grid</option>
                    </select>
                </div>
                <div>
                    <label>Show Errors</label>
                    <select id='show_errors' class='form-control browser-default'>
                        <option value='interaction'>On Interaction</option>
                        <option value='change'>On Field Change</option>
                        <option value='always'>Always</option>
                        <option value='never'>Never</option>
                    </select>
                </div>
                <div>
                    <label>Boolean options</label>
                    <select multiple size="9" id="boolean_options" style="width: 100%; height: inherit;" class="form-control browser-default">
                        <option value='required_by_default'>Object properties required by default</option>
                        <option value='display_required_only'>Only show required properties by default</option>
                        <option value='no_additional_properties'>No additional object properties</option>
                        <option value='ajax'>Allow loading schemas via Ajax</option>
                        <option value='disable_edit_json'>Disable "Edit JSON" buttons</option>
                        <option value='disable_collapse'>Disable collapse buttons</option>
                        <option value='disable_properties'>Disable properties buttons</option>
                        <option value='disable_array_add'>Disable array add buttons</option>
                        <option value='disable_array_reorder'>Disable array move buttons</option>
                        <option value='disable_array_delete'>Disable array delete buttons</option>
                        <option value='enable_array_copy'>Add copy buttons to arrays</option>
                        <option value='array_controls_top'>Array controls will be displayed at top of list</option>
                        <option value='disable_array_delete_all_rows'>Disable array delete all rows buttons</option>
                        <option value='disable_array_delete_last_row'>Disable array delete last row buttons</option>
                    </select>
                </div>
                <div>
                    <label title="It's reccomended that you click the Direct Link after changing these options">Include External Library</label>
                    <select multiple size="8" id='lib_switcher' style="width: 100%; height: inherit;" class='form-control browser-default' title="It's reccomended that you click the Direct Link after changing these options">
                        <option value='ace_editor'>Ace Editor</option>
                        <option value='sceditor'>SCEditor</option>
                        <option value='simplemde'>SimpleMDE</option>
                        <option value='select2'>Select2</option>
                        <option value='selectize'>Selectize</option>
                        <option value='flatpickr'>Flatpickr</option>
                        <option value='signature_pad'>Signature Pad</option>
                        <option value='mathjs'>Math.js</option>
                    </select>
                </div>
            </div>

            <h2>Validation</h2>
            <p>This will update whenever the form changes to show validation errors if there are any.</p>
            <textarea id='validate' style='width: 100%; height: 100px; font-family: monospace;' readonly disabled class='form-control'></textarea>
        </div>
    </div>
    <div class='row'>
        <div class='row'>
            <div class='span12 col-md-12 columns twelve large-12 col s12'>
                <h2>Schema</h2>
                <p>You can change the schema and see how the generated form looks.  After you make changes, click <button class='btn btn-primary' id='setschema'>Update Schema</button></p>

                <textarea id='schema' style='width: 100%; height: 450px; font-family: monospace;' class='form-control'></textarea>
            </div>
        </div>
        <div class='row' style='display:none'>
            <div class='span12 col-md-12 columns twelve large-12 col s12'>
                <h2>Code</h2>
      <pre><code>// Set default options
JSONEditor.defaults.options.theme = 'bootstrap2';

// Initialize the editor
var editor = new JSONEditor(document.getElementById("editor_holder"),{
  schema: {
      type: "object",
      properties: {
          name: { "type": "string" }
      }
  }
});

// Set the value
editor.setValue({
    name: "John Smith"
});

// Get the value
var data = editor.getValue();
console.log(data.name); // "John Smith"

// Validate
var errors = editor.validate();
if(errors.length) {
  // Not valid
}

// Listen for changes
editor.on("change",  function() {
  // Do something...
});</code></pre>
            </div>
        </div>
    </div>
</div>
<p>&nbsp;</p>
<script>
(function() {
    var schema;
    if(window.location.href.match('[?&]schema=([^&]+)')) {
        try {
            schema = JSON.parse(LZString.decompressFromBase64(window.location.href.match('[?&]schema=([^&]+)')[1]));
        }
        catch(e) {
            console.log('invalid starting schema');
        }
    }

    // Default starting schema
    if(!schema) {
        schema = {
            title: "Settings",
            type: "object",
            "required": [
              'Session',
              'Forward',
              'Optode',
              'Shapes',
              'Domain',
            ],
	    format: "categories",
            properties: {
                Session: {
                    type: "object",
                    title: "Session",
		    format: "grid",	    
		    required: ["ID", "Photons", "DoMismatch", "DoAutoThread"],
                    properties: {
                        ID: {
			    title: "Session Name",
                            type: "string",
                            default: "mcx"
                        },
                        Photons: {
			    title: "Photon number",
                            type: "integer",
                            default: 100000,
			    maximum: 10000000
                        },
			DoMismatch: {
			    title: "Do Reflection",
                            type: "boolean",
                            default: true
                        },
			DoAutoThread: {
			    title: "Let MCX decide thread/block size",
                            type: "boolean",
                            default: true
                        },
                        RNGSeed: {
			    title: "Random seed",
                            type: "number",
			    required: false,
                            default: 29012392
                        },
                    }
                },
                Forward: {
                    type: "object",
                    title: "Forward",
		    format: "grid",
		    required: ["T0", "T1", "Dt"],
                    properties: {
                        T0: {
			    title: "Starting time",
                            type: "number",
                            default: 0,
			    minimum: 0,
			    maximum: 1e-7
                        },
                        T1: {
			    title: "Ending time",
                            type: "number",
                            default: 5e-9,
			    minimum: 0,
			    maximum: 1e-7
                        },
                        Dt: {
			    title: "Time gate width",
                            type: "number",
                            default: 5e-9,
			    minimum: 0,
			    maximum: 1e-7
                        },
                    }
                },
                Optode: {
                    type: "object",
                    title: "Optode",
		    required: ["Source"],
                    properties: {
                        Source: {
			    title: "Source",
                            type: "object",
			    "required": [ "Type", "Pos", "Dir"],
			    properties: {
				Type: {
				    title: "Type",
				    type: "string",
				    default: "pencil",
				    "enum": ["pencil", "isotropic", "cone", 
				          "gaussian", "planar", "pattern", "pattern3d",
					  "fourier", "arcsine", "disk", "fourierx",
					  "fourierx2d", "zgaussian", "line", "slit", "pencilarray"]
				},
				Pos: {
				    title: "Position",
				    type: "array",
				    format: "tabs",
				    items: {
					     "type": "number",
				    },
				    default: [30,30,0],
				    minItems: 3,
				    maxItems: 3
				},
				Dir: {
				    title: "Launch Direction",
				    type: "array",
				    format: "tabs",
				    default: [0,0,1],
				    items: {
					     "type": "number"
				    },
				    minItems: 3,
				    maxItems: 4
				},
				Param1: {
				    title: "Source Parameter 1",
				    type: "array",
				    required: false,
				    format: "tabs",
				    items: {
					     "type": "number"
				    },
				    "minItems": 4,
				    "maxItems": 4
				},
				Param2: {
				    title: "Source Parameter 1",
				    type: "array",
				    required: false,
				    format: "tabs",
				    items: {
					     "type": "number"
				    },
				    "minItems": 4,
				    "maxItems": 4
				},
			    }
                        },
                        Detector: {
			    title: "Detector",
                            type: "array",
			    required: false,
			    format: "table",
			    items: {
			      "type": "object",
			      "required": [ "Pos", "R" ],
			      "properties": {
				Pos: {
				    title: "Position",
				    type: "array",
				    items: {
					     "type": "number"
				    },
				    "minItems": 3,
				    "maxItems": 3
				},
				R: {
				    title: "Radius",
				    type: "number",
				    default: 2,
				    minimum: 0,
				}
			      }
                        }
                    }
	        }
	    },
            Shapes: {
                    type: "array",
		    title: "Shapes",
		    format: "table",
		    items: {
		    type: [
		      {
		        title: "Grid",
			type: "object",
			required: ["Tag","Size"],
			items: {
			  "properties": {
			    "Tag": {
			      title: "Tag",
			      "type": "integer",
			      default: 1,
			      minimum: 0
			    },
			    "Size": {
				    title: "Size",
				    type: "array",
				    format: "tabs",
				    items: {
					     "type": "number"
				    },
				    default: [60,60,60],
				    "minItems": 3,
				    "maxItems": 3
			    }
			}
		       }
		      },
		      {
		        title: "Sphere",
			type: "object",
			required: ["Tag","O","R"],
			"properties": {
			  "Tag": {
			    title: "Tag",
			    "type": "integer",
			    minimum: 0
			  },
			  "O": {
				    title: "Center",
				    type: "array",
				    format: "tabs",
				    items: {
					     "type": "number"
				    },
				    "minItems": 3,
				    "maxItems": 3
			  },
			  "R": {
			    title: "Radius",
			    "type": "number",
			    minimum: 0
			  },
			}
		      },
		      {
		        title: "Box",
			type: "object",
			required: ["Tag","O","Size"],
			"properties": {
			  "Tag": {
			    title: "Tag",
			    "type": "integer",
			    minimum: 0
			  },
			  "Size": {
				    title: "Size",
				    type: "array",
				    format: "tabs",
				    items: {
					     "type": "number"
				    },
				    "minItems": 3,
				    "maxItems": 3
			  },
			  "O": {
				    title: "Center",
				    type: "array",
				    format: "tabs",
				    items: {
					     "type": "number"
				    },
				    "minItems": 3,
				    "maxItems": 3
			  },
			}
		      },
		      {
		        title: "Subgrid",
			type: "object",
			required: ["Tag","O","Size"],
			"properties": {
			  "Tag": {
			    title: "Tag",
			    "type": "integer",
			    minimum: 0
			  },
			  "Size": {
				    title: "Size",
				    type: "array",
				    format: "tabs",
				    items: {
					     "type": "number"
				    },
				    "minItems": 3,
				    "maxItems": 3
			  },
			  "O": {
				    title: "Center",
				    type: "array",
				    format: "tabs",
				    items: {
					     "type": "number"
				    },
				    "minItems": 3,
				    "maxItems": 3
			  },
			}
		      },
		      {
		        title: "Cylinder",
			type: "object",
			required: ["Tag","C0","C1","R"],
			"properties": {
			  "Tag": {
			    title: "Tag",
			    "type": "integer",
			    minimum: 0
			  },
			  "C0": {
				    title: "Size",
				    type: "array",
				    format: "tabs",
				    items: {
					     "type": "number"
				    },
				    "minItems": 3,
				    "maxItems": 3
			  },
			  "C1": {
				    title: "Center",
				    type: "array",
				    format: "tabs",
				    items: {
					     "type": "number"
				    },
				    "minItems": 3,
				    "maxItems": 3
			  },
			  "R": {
			    title: "Radius",
			    "type": "number",
			    minimum: 0
			  },
			}
		      },
		      {
		        title: "Name",
			type: "string",
		      }
		    ]
                }
            },
            Domain: {
                    type: "object",
                    title: "Domain",
		    required: ["Media","Dim","OriginType"],
                    properties: {
                        OriginType: {
			    title: "Origin at [0,0,0]",
                            type: "boolean",
			    default: true
                        },
			Dim: {
			    title: "Dimensions",
			    type: "array",
			    format: "tabs",
			    items: {
				     "type": "integer"
			    },
			    default: [60,60,60],
			    "minItems": 3,
			    "maxItems": 3
			},
                        VolumeFile: {
			    title: "Volume File",
                            type: "string",
			    required: false,
			    default: ""
                        },
                        Media: {
			    title: "Media",
                            type: "array",
			    format: "table",
			    "minItems": 2,
			    items: {
			      "type": "object",
			      "required": [ "mua", "mus", "g", "n" ],
			      "properties": {
				mua: {
				    title: "Absorption (μa 1/mm)",
				    type: "number",
				    default: 0,
				    minimum: 0,
				},
				mus: {
				    title: "Scattering (μs 1/mm)",
				    type: "number",
				    default: 0,
				    minimum: 0,
				},
				g: {
				    title: "Anisotropy (g)",
				    type: "number",
				    default: 1,
				    minimum: -1,
				    maximum: 1,
				},
				n: {
				    title: "Reflective Index (n)",
				    type: "number",
				    default: 1,
				    minimum: 0,
				}
			      }
                        }
                    }
	        }
            },
	}
      }
    }

    // Divs/textareas on the page
    var $schema = document.getElementById('schema');
    var $output = document.getElementById('output');
    var $editor = document.getElementById('editor');
    var $validate = document.getElementById('validate');

    // Buttons
    var $set_schema_button = document.getElementById('setschema');
    var $set_value_button = document.getElementById('setvalue');

    var jsoneditor;

    // Function for loading external javascript(s) during runtime
    var loadScripts = function(urls, lib) {

      var head = document.getElementsByTagName('head')[0],
          scripts = Array.prototype.slice.call(head.getElementsByTagName('script')).map(function(key) {return key.src.toLowerCase();})

      if (typeof urls == 'string') urls = [urls];

      return new Promise(
        function(resolve, reject) {
          for (var i=0;i<urls.length;i++) {

            if (scripts.indexOf(urls[i].toLowerCase()) == -1) {
              var script = document.createElement('script');
              script.classList.add('external_' + lib)
              script.type = 'text/javascript';
              script.src = urls[i];
              script.async = false;

              // If last script, bind the callback event to resolve
              if (i == urls.length-1) {
                  // Multiple binding for browser compatibility
                  script.onreadystatechange = resolve;
                  script.onload = resolve;
              }

              // Fire the loading
              head.appendChild(script);
            }

          }
        }
      );
    }

    var updateDirectLink = function() {
        var url = window.location.href.replace(/\?.*/,'');

        url += '?schema='+LZString.compressToBase64(JSON.stringify(schema));
        url += '&value='+LZString.compressToBase64(JSON.stringify(jsoneditor.getValue()));
        //url += JSONEditor.plugins.selectize.enable ? '&enable_selectize=1':'';

        var libs = document.getElementById('lib_switcher').querySelectorAll(':checked');
        var result = Object.keys(libs).map(function(key) {return libs[key].value;});
        url += '&lib_switcher=' + result.join(',');

        for(var i in JSONEditor.defaults.options) {
            if(!JSONEditor.defaults.options.hasOwnProperty(i)) continue;
            if(JSONEditor.defaults.options[i]===false) continue;
            else if(JSONEditor.defaults.options[i]===true) {
                url += '&'+i;
            }
            else {
                url += '&'+i+'='+JSONEditor.defaults.options[i];
            }
        }
        document.getElementById('direct_link').href = url;
    };

    var reload = function(keep_value) {
        var startval = (jsoneditor && keep_value)? jsoneditor.getValue() : window.startval;
        window.startval = undefined;

        if(jsoneditor) jsoneditor.destroy();
        jsoneditor = new JSONEditor($editor,{
            schema: schema,
            startval: startval,
        });
        window.jsoneditor = jsoneditor;

        // When the value of the editor changes, update the JSON output and validation message
        jsoneditor.on('change',function() {
            var json = jsoneditor.getValue();

            $output.value = JSON.stringify(json,null,2);

            var validation_errors = jsoneditor.validate();
            // Show validation errors if there are any
            if(validation_errors.length) {
                $validate.value = JSON.stringify(validation_errors,null,2);
            }
            else {
                $validate.value = 'valid';
            }

            updateDirectLink();

            // Materialize extra.
            if (window.Materialize) window.Materialize.updateTextFields();

        });
    };

    // Start the schema and output textareas with initial values
    $schema.value = JSON.stringify(schema,null,2);
    $output.value = '';

    // When the 'update form' button is clicked, set the editor's value
    $set_value_button.addEventListener('click',function() {
        jsoneditor.setValue(JSON.parse($output.value));
    });

    // Update the schema when the button is clicked
    $set_schema_button.addEventListener('click',function() {
        try {
            schema = JSON.parse($schema.value);
        }
        catch(e) {
            alert('Invalid Schema: '+e.message);
            return;
        }

        reload();
    });

    // Set the theme by loading the right stylesheets
    var setTheme = function(theme,no_reload) {
        theme = theme || '';

        var mapping = {
            barebones: '',
            html: '',
            bootstrap2: 'https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css',
            bootstrap3: 'https://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css',
            bootstrap4: 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css',
            foundation3: 'https://cdnjs.cloudflare.com/ajax/libs/foundation/3.2.5/stylesheets/foundation.css',
            foundation4: 'https://cdnjs.cloudflare.com/ajax/libs/foundation/4.3.2/css/foundation.min.css',
            foundation5: 'https://cdnjs.cloudflare.com/ajax/libs/foundation/5.5.3/css/foundation.min.css',
            foundation6: 'https://cdnjs.cloudflare.com/ajax/libs/foundation/6.2.4/foundation.min.css',
            jqueryui: 'https://code.jquery.com/ui/1.10.3/themes/south-street/jquery-ui.css',
            materialize: 'https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css'
        };

        if(typeof mapping[theme] === 'undefined') {
            theme = 'bootstrap3';
            document.getElementById('theme_switcher').value = theme;
        }

        var scriptMapping = {
            materialize: [
                'https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js',
                'https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js'
            ]
        }

        var themeScripts = scriptMapping[theme],
            head = document.getElementsByTagName('head')[0],
            script;

        if (typeof themeScripts == 'string') { themeScripts = [themeScripts]; }
        if (Array.isArray(themeScripts)) {
            for (var i = 0; i < themeScripts.length; i++) {
                script = document.createElement('script');
                script.type = 'text/javascript';
                script.src = themeScripts[i];
                head.appendChild(script);
            }
        }

        JSONEditor.defaults.options.theme = theme;

        document.getElementById('theme_stylesheet').href = mapping[theme];
        document.getElementById('theme_switcher').value = JSONEditor.defaults.options.theme;

        if(!no_reload) reload(true);
    };

    // Set the icontheme by loading the right stylesheets
    var setIconlib = function(iconlib,no_reload) {
        iconlib = iconlib || '';
        var mapping = {
            foundation2: 'https://cdnjs.cloudflare.com/ajax/libs/foundicons/2.0/stylesheets/general_foundicons.css',
            foundation3: 'https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.css',
            fontawesome3: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/3.2.1/css/font-awesome.css',
            fontawesome4: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.css',
            materialicons: 'https://fonts.googleapis.com/icon?family=Material+Icons'
        };

        JSONEditor.defaults.options.iconlib = iconlib;

        document.getElementById('icon_stylesheet').href = mapping[iconlib] || '';
        document.getElementById('icon_switcher').value = JSONEditor.defaults.options.iconlib;

        if(!no_reload) reload(true);
    };

    // Set the external library inclusion
    var setExternalLib = function(lib_name, no_reload) {

        lib_name = lib_name || '';

        var scriptMapping = {
          ace_editor: "https://cdn.jsdelivr.net/npm/ace-editor-builds@1.2.4/src-min-noconflict/ace.js",
          sceditor: [
            "https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js",
            "https://cdn.jsdelivr.net/npm/sceditor@2.1.3/minified/sceditor.min.js",
            "https://cdn.jsdelivr.net/npm/sceditor@2.1.3/minified/formats/bbcode.js",
            "https://cdn.jsdelivr.net/npm/sceditor@2.1.3/minified/formats/xhtml.js"
          ],
          simplemde: "https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js",
          select2: [
            "https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js",
            "https://cdn.jsdelivr.net/npm/select2@4.0.6-rc.1/dist/js/select2.min.js"
          ],
          selectize: "https://cdn.jsdelivr.net/npm/selectize@0.12.6/dist/js/standalone/selectize.min.js",
          flatpickr: "https://cdn.jsdelivr.net/npm/flatpickr",
          signature_pad: "https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad.min.js",
          mathjs: "https://cdn.jsdelivr.net/npm/mathjs@5.3.1/dist/math.min.js"
        }

        var styleMapping = {
          sceditor: "https://cdn.jsdelivr.net/npm/sceditor@2.1.3/minified/themes/default.min.css",
          select2: "https://cdn.jsdelivr.net/npm/select2@4.0.6-rc.1/dist/css/select2.min.css",
          selectize: [
            "https://cdn.jsdelivr.net/npm/selectize@0.12.6/dist/css/selectize.min.css",
            "https://cdn.jsdelivr.net/npm/selectize@0.12.6/dist/css/selectize.default.min.css"
          ],
          simplemde: "https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css",
          flatpickr: "https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css"
        }

        var libScripts = scriptMapping[lib_name],
            libStyles = styleMapping[lib_name],
            head = document.getElementsByTagName('head')[0],
            script,style;

        if (typeof libStyles == 'string') { libStyles = [libStyles]; }
        if (Array.isArray(libStyles)) {
            for (var i = 0; i < libStyles.length; i++) {
                style = document.createElement('link');
                style.setAttribute('rel', 'stylesheet');
                style.setAttribute('type', 'text/css');
                style.setAttribute('href', libStyles[i]);
                style.classList.add('external_' + lib_name);
                head.appendChild(style);
            }
        }

        if (libScripts !== undefined) {
          loadScripts(libScripts, lib_name).then(
            function(val) {
              switch (lib_name) {
                case 'selectize':
                  JSONEditor.plugins.selectize.enable = true;
                  break;
              }

              if(!no_reload) {
                reload(true);
              }
            }
          ).catch(
            function(reason) {
              console.log('Error loading script: ', reason)
            }
          );
        }
    }

    var refreshBooleanOptions = function(no_reload) {
        var boolean_options = document.getElementById('boolean_options').children;
        for(var i=0; i<boolean_options.length; i++) {
            JSONEditor.defaults.options[boolean_options[i].value] = boolean_options[i].selected;
        }
        if(!no_reload) reload(true);
    };

    // Change listeners for options
    document.getElementById('theme_switcher').addEventListener('change',function() {
        setTheme(this.value);
    });
    document.getElementById('icon_switcher').addEventListener('change',function() {
        setIconlib(this.value);
    });
    document.getElementById('lib_switcher').addEventListener('change',function() {
      var selected = this.querySelectorAll(':checked'),
          unselected = this.querySelectorAll(':not(:checked)');

      for (var i=0;i<unselected.length;i++) {
        var els = document.getElementsByTagName('head')[0].getElementsByClassName('external_' + unselected[i].value);
        for (var j=els.length-1;j>=0;j--) {
          if (unselected[i].value == 'selectize') JSONEditor.plugins.selectize.enable = false;
          els[j].parentNode.removeChild(els[j]);
        }
      }

      for (var i=0;i<selected.length;i++) {
        if (selected[i].value == 'selectize') JSONEditor.plugins.selectize.enable = true;
        setExternalLib(selected[i].value);
      }
    });
    document.getElementById('object_layout').addEventListener('change',function() {
       JSONEditor.defaults.options.object_layout = this.value;
        reload(true);
    });
    document.getElementById('show_errors').addEventListener('change',function() {
       JSONEditor.defaults.options.show_errors = this.value;
        reload(true);
    });
    document.getElementById('boolean_options').addEventListener('change',function() {
        refreshBooleanOptions();
    });

    // Get starting value from url
    if(window.location.href.match('[?&]value=([^&]+)')) {
      window.startval = JSON.parse(LZString.decompressFromBase64(window.location.href.match('[?&]value=([^&]+)')[1]));
    }

    // Set options from direct link
    setTheme((window.location.href.match(/[?&]theme=([^&]+)/)||[])[1] || 'bootstrap2', true);

    setIconlib((window.location.href.match(/[?&]iconlib=([^&]*)/)||[null,'fontawesome4'])[1], true);

    document.getElementById('object_layout').value = (window.location.href.match(/[?&]object_layout=([^&]+)/)||[])[1] || 'normal';
    JSONEditor.defaults.options.object_layout = document.getElementById('object_layout').value;

    document.getElementById('show_errors').value = (window.location.href.match(/[?&]show_errors=([^&]+)/)||[])[1] || 'interaction';
    JSONEditor.defaults.options.show_errors = document.getElementById('show_errors').value;

    var lib_switcher = document.getElementById('lib_switcher');
    var lib_switcher_values = ((window.location.href.match(/[?&]lib_switcher=([^&]+)/)||[])[1] || '');
    if (lib_switcher_values != '') {
      lib_switcher_values = lib_switcher_values.split(',');
      for (var i=0;i< lib_switcher.options.length;i++) {
        lib_switcher.options[i].selected = (lib_switcher_values.indexOf(lib_switcher.options[i].value)>-1);
        if (lib_switcher.options[i].selected) setExternalLib(lib_switcher.options[i].value);
      }
    }

    var boolean_options = document.getElementById('boolean_options').children;
    for(var i=0; i<boolean_options.length; i++) {
        if(window.location.href.match(new RegExp('[?&]'+boolean_options[i].getAttribute('value')+'([&=]|$)'))) {
            boolean_options[i].selected = true;
        }
    }
    refreshBooleanOptions(true);

    reload();
})();
</script>
</body>
</html>
